﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using System.Xml;
using System.Xml.Xsl;
using System.IO;

namespace Ex1MusicCompany
{
    class XMLProcessingTasks
    {
        static void Main()
        {
            //Ex1CreateAlbums();
            //Ex2DomParsing();
            //Ex3XPathArtistAlbumsCount();
            //Ex4RemovePricedOver20Albums();
            //Ex5ExtractSongTitlesWithXMLReader();
            //Ex6XDocPlusLinqExtractTitles();
            //Ex7DOMXMLCreatePersons();
            //Ex8ExtractAlbumsViaXMLReaderXMLWriter();
            //Ex9DirsToXMLViaXMLWriter();
            //Ex10LinqRecurseDir();
            //Ex11AlbumsBefore5Years();
            //Ex11AlbumsBefore5YearsViaLINQ();
            //Ex12And13XSLTransformation();

        }
  
        private static void Ex12And13XSLTransformation()
        {
            XslCompiledTransform transformer = new XslCompiledTransform();
            transformer.Load(@"..\..\XSLTF_CatalogToHTML.xslt");
            transformer.Transform(@"..\..\musicCatalog.xml", @"..\..\TransformedCatalog.html");
        }
  
        private static void Ex11AlbumsBefore5YearsViaLINQ()
        {
            XElement root = XElement.Load(@"..\..\musicCatalog.xml");
            var childs =
            from n in root.Descendants("album")
            where int.Parse(n.Element("year").Value) < 2006                  
            select n.Element("price");

            foreach (var item in childs)
            {
                Console.WriteLine(item.Value);
            }
        }
  
        private static void Ex11AlbumsBefore5Years()
        {
            string catalogPath = @"..\..\musicCatalog.xml";

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(catalogPath);
            string xPathQuery = "/albums/album[year<2006]";
              
            foreach (XmlNode n in xmlDoc.SelectNodes(xPathQuery))
            {
                Console.WriteLine(n["price"].InnerText);                
            }
        }
  
        private static void Ex10LinqRecurseDir()
        {
            XElement root = new XElement(@"root", "");
            DirectoryInfo rootDir = new DirectoryInfo(@"e:\downloads\");
            LinqRecurse(rootDir, root);
            root.Save(@"..\..\DirScanViaLinq.xml");
        }

        private static void LinqRecurse(DirectoryInfo currentDir, XElement currentNode)
        {
            XAttribute attr = new XAttribute("name", currentDir.Name);
            currentNode.Add(attr);

            foreach (var d in currentDir.GetDirectories())
            {
                XElement cd = new XElement("dir", "");
                currentNode.Add(cd);
                LinqRecurse(d, cd);
            }
            
            foreach (var f in currentDir.GetFiles())
            {
                XElement fe = new XElement("file", f.Name);
                currentNode.Add(fe);
            }
            //Console.WriteLine(currentNode);            
        }
  
        private static void Ex9DirsToXMLViaXMLWriter()
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            settings.IndentChars = "\t";
            settings.NewLineOnAttributes = false;

            XmlWriter writer = XmlWriter.Create(@"..\..\DirsAndFiles.xml", settings);
            RecursiveScan(@"C:\.Net Essentials TFS\Subev", writer);
        }

        private static void RecursiveScan(string path,XmlWriter writer)
        {
            DirectoryInfo currentDir = new DirectoryInfo(path);
            writer.WriteStartElement("dir");
            writer.WriteAttributeString("name", currentDir.Name);
            foreach (var dir in currentDir.GetDirectories())
            {
                RecursiveScan(dir.FullName, writer);
            }
            foreach (var file in currentDir.GetFiles())
            {
                writer.WriteElementString("file", file.Name);
            }
            writer.WriteEndElement();
        }
  
        private static void Ex8ExtractAlbumsViaXMLReaderXMLWriter()
        {
            using (XmlReader xReader = XmlReader.Create(@"..\..\musicCatalog.xml"))
            {
                XmlWriterSettings settings = new XmlWriterSettings();
                settings.Indent = true;
                settings.IndentChars = "  ";
                settings.NewLineOnAttributes = true;

                using (XmlWriter writer = XmlWriter.Create(@"..\..\ExtractedAlbumsAndAuthors.xml", settings))
                {
                    writer.WriteStartElement("albums");
                    while (xReader.Read())
                    {
                        if (xReader.NodeType == XmlNodeType.Element && xReader.Name == "name")
                        {
                            writer.WriteStartElement("album");
                            writer.WriteElementString("albumName", xReader.ReadElementString());
                        }
                        if (xReader.NodeType == XmlNodeType.Element && xReader.Name == "artist")
                        {
                            writer.WriteElementString("Artist", xReader.ReadElementString());
                            writer.WriteEndElement();
                        }
                    }
                    writer.WriteEndDocument();
                }
            }
        }

        private static void Ex7DOMXMLCreatePersons()
        {
            StreamReader reader = new StreamReader(@"..\..\personsPlain.txt");
            using (reader)
            {
                XmlDocument catalogWr = new XmlDocument();
                var basicNode = catalogWr.CreateNode(XmlNodeType.Element, "persons", "");
                catalogWr.AppendChild(basicNode);
                while (!reader.EndOfStream)
                {
                    string line = reader.ReadLine();
                    string[] parameters = line.Split('|');
                    string name = parameters[0].Trim();
                    string address = parameters[1].Trim();
                    string phone = parameters[2].Trim();

                    var person = catalogWr.CreateNode(XmlNodeType.Element, "person", "");

                    var nameNode = catalogWr.CreateNode(XmlNodeType.Element, "name", "");
                    nameNode.AppendChild(catalogWr.CreateTextNode(name));
                    person.AppendChild(nameNode);

                    var addressNode = catalogWr.CreateNode(XmlNodeType.Element, "adress", "");
                    addressNode.AppendChild(catalogWr.CreateTextNode(address));
                    person.AppendChild(addressNode);

                    var phoneNode = catalogWr.CreateNode(XmlNodeType.Element, "phone", "");
                    phoneNode.AppendChild(catalogWr.CreateTextNode(phone));
                    person.AppendChild(phoneNode);

                    basicNode.AppendChild(person);
                }
                catalogWr.Save(@"..\..\Persons.xml");
            }
        }

        private static void Ex6XDocPlusLinqExtractTitles()
        {
            XDocument catalog = XDocument.Load(@"..\..\musicCatalog.xml");
            var titles =
            from n in catalog.Descendants()
            where n.NodeType == XmlNodeType.Element && n.Name == "title"
            select n.Value;
            foreach (var item in titles)
            {
                Console.WriteLine(item);
            }
        }

        private static void Ex5ExtractSongTitlesWithXMLReader()
        {
            using (XmlReader xReader = XmlReader.Create(@"..\..\musicCatalog.xml"))
            {
                while (xReader.Read())
                {
                    if (xReader.NodeType == XmlNodeType.Element && xReader.Name == "title")
                    {
                        Console.WriteLine(xReader.ReadElementContentAsString());
                    }
                }
            }
        }

        private static void Ex4RemovePricedOver20Albums()
        {
            XmlDocument catalog = new XmlDocument();
            catalog.Load(@"..\..\musicCatalog.xml");
            var nodes = catalog.SelectNodes(@"/albums/album/price");
            foreach (XmlNode node in nodes)
            {
                if (double.Parse(node.InnerText) > 20)
                {
                    catalog["albums"].RemoveChild(node.ParentNode);
                }
            }
            catalog.Save(@"..\..\musicCatalog.xml");
        }

        private static void Ex3XPathArtistAlbumsCount()
        {
            XmlDocument catalog = new XmlDocument();
            catalog.Load(@"..\..\musicCatalog.xml");
            string pathToArtist = @"/albums/album/artist";
            Dictionary<string, int> artistAlmubs = new Dictionary<string, int>();
            foreach (XmlNode node in catalog.SelectNodes(pathToArtist))
            {
                if (!artistAlmubs.ContainsKey(node.InnerText))
                {
                    artistAlmubs.Add(node.InnerXml, 0);
                }
                artistAlmubs[node.InnerText]++;
            }
            foreach (var item in artistAlmubs)
            {
                Console.WriteLine("{0} {1}", item.Key, item.Value);
            }
        }

        private static void Ex2DomParsing()
        {
            XmlDocument mc = new XmlDocument();
            mc.Load(@"..\..\musicCatalog.xml");
            XmlElement root = mc.DocumentElement;
            Dictionary<string, int> albumsOfArtist = new Dictionary<string, int>();
            foreach (XmlNode album in root.ChildNodes)
            {
                string artist = album["artist"].InnerText;
                if (!albumsOfArtist.ContainsKey(artist))
                {
                    albumsOfArtist.Add(artist, 0);
                }
                albumsOfArtist[artist]++;
            }

            foreach (var item in albumsOfArtist)
            {
                Console.WriteLine("{0} {1}", item.Key, item.Value);
            }
        }

        private static void Ex1CreateAlbums()
        {
            XElement musicCatalog =
            new XElement("albums",
                         new XElement("album",
                                      new XElement("name", "Get Rich Or Die Tryin"),
                                      new XElement("artist", "50 cent"),
                                      new XElement("year", "2003"),
                                      new XElement("prudecer", "G UNIT"),
                                      new XElement("price", "12"),
                                      new XElement("songs",
                                                   new XElement("song",
                                                                new XElement("title", "In da club"),
                                                                new XElement("duration", "5.50")),
                                                   new XElement("song",
                                                                new XElement("title", "Many Man"),
                                                                new XElement("duration", "3.40")))),

                         new XElement("album",
                                      new XElement("name", "Meteora"),
                                      new XElement("artist", "linkin park"),
                                      new XElement("year", "2003"),
                                      new XElement("prudecer", "some prod"),
                                      new XElement("price", "110"),
                                      new XElement("songs",
                                                   new XElement("song",
                                                                new XElement("title", "From you"),
                                                                new XElement("duration", "3.40")),
                                                   new XElement("song",
                                                                new XElement("title", "FigNo.9"),
                                                                new XElement("duration", "2.20")))));

            musicCatalog.Save(@"..\..\musicCatalog.xml");
        }
    }
}
